package com.hjb.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hjb.entity.User;
import com.hjb.entity.UserLog;
import com.hjb.mapper.UserInfoMapper;
import com.hjb.mapper.UserLogMapper;
import com.hjb.service.UserLogService;
import com.hjb.vo.UserLogVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author HuJiaBing
 * @date 2025/6/28 9:58
 */
@Service
public class UserLogServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implements UserLogService {
    @Resource
    private UserInfoMapper userInfoMapper;

    /**
     * 获取所有用户日志
     * demo测试：在不使用事务的情况下，可以任意切换数据源。
     * @return 用户日志
     */
    @Override
    public List<UserLogVO> getAllUserLog() {
        List<UserLog> userLogs = this.baseMapper.selectList(new QueryWrapper<>());
        List<Long> userIds = userLogs.stream().map(UserLog::getUserId).collect(Collectors.toList());
        List<User> users = userInfoMapper.selectBatchIds(userIds);
        Map<Long, String> userMap = users.stream().collect(Collectors.toMap(User::getId, User::getName));
        return userLogs.stream().map(userLog -> {
            UserLogVO userLogVO = new UserLogVO();
            BeanUtils.copyProperties(userLog, userLogVO);
            userLogVO.setUserName(userMap.get(userLog.getUserId()));
            return userLogVO;
        }).collect(Collectors.toList());
    }

    /**
     * 保存所有用户日志
     * demo测试: 无事务的情况下可以任意切换数据源
     */
    @Override
    public void saveAll() {
        // 保存用户
        User user = new User();
        user.setName("testUser");
        userInfoMapper.insert(user);
        // 保存日志
        UserLog userLog = new UserLog();
        userLog.setUserId(user.getId());
        userLog.setContent("test to add log");
        this.baseMapper.insert(userLog);
    }

    /**
     * demo测试: 使用Transactional注解，数据源不能正常切换
     */
    @Override
    @Transactional
    public void saveAllWithTransaction() {
        // 保存用户
        User user = new User();
        user.setName("testUserTransactional");
        userInfoMapper.insert(user);
        // 保存日志
        UserLog userLog = new UserLog();
        userLog.setUserId(user.getId());
        userLog.setContent("Transactional:test to add log");
        this.baseMapper.insert(userLog);
    }

    /**
     * demo测试: 使用DSTransactional注解，数据源可以正常切换
     */
    @Override
    @DSTransactional
    public void saveAllWithDSTransactional() {
        // 保存用户
        User user = new User();
        user.setName("testUserDSTransactional");
        userInfoMapper.insert(user);
        // 保存日志
        UserLog userLog = new UserLog();
        userLog.setUserId(user.getId());
        userLog.setContent("DSTransactional:test to add log");
        this.baseMapper.insert(userLog);
    }

    /**
     * demo测试: 使用DSTransactional注解，数据源可以正常切换，出现异常时，事务能够正常回滚。
     */
    @Override
    @DSTransactional
    public void saveAllWithDSTransactionalTestRollback() {
        // 保存用户
        User user = new User();
        user.setName("testUserDSTransactional-Rollback");
        userInfoMapper.insert(user);
        // 保存日志
        UserLog userLog = new UserLog();
        userLog.setUserId(user.getId());
        userLog.setContent("DSTransactional:test to add log");
        this.baseMapper.insert(userLog);
        // 测试事务回滚
        int i = 1 / 0;
    }

    @Override
    @DSTransactional
    public void saveLog() {
        UserLog userLog = new UserLog();
        userLog.setUserId(1L);
        userLog.setContent("test to add log");
        this.baseMapper.insert(userLog);
//        throw new RuntimeException("测试事务回滚");
    }


}
